package com.kayak.easysp.util;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.alibaba.dubbo.rpc.RpcException;
import com.kayak.dubbo.bean.ConsumerBean;
import com.kayak.dubbo.bean.RpcBean;
import com.kayak.easysp.transbase.TransBean;
import com.kayak.exception.ErrorException;
import com.kayak.kkutils.CalendarUtil;
import com.kayak.kkweb.sys.Global;
import com.kayak.service.security.acctlevel.ChkAcctSecurityStepInterface;
import com.kayak.service.security.acctlevel.QryAcctSecurityStepInterface;

/**
 * 字符串处理公共方法 
 * */
public class TransUtilEasysp {

	protected final static Logger log = LoggerFactory.getLogger(TransUtilEasysp.class);
	
	@Autowired
	static ChkAcctSecurityStepInterface chkAcctSecurityStepService;//查询用户安全步骤完成情况
	@Autowired
	static QryAcctSecurityStepInterface qryAcctSecurityStepService;//查询用户安全步骤

	// 时间格式
	public final static String dateTimeFormat = "yyyyMMddHHmmss";
	
	public final static String dateFormat = "yyyyMMdd";
	
	public final static String timeFormat = "HHmmss";
	
	private final static String[] chars = new String[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
		"o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8",
		"9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
		"U", "V", "W", "X", "Y", "Z" };

	// 邮箱验证
	public final static String		EMAIL					= "^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";
		
	/**
	 * @param srcStr
	 *            源字符串
	 * @param splitChar
	 *            分割符
	 * @return descStr 目标字符串
	 * 
	 * */
	public static String subStrBySplit(String srcStr, String splitChar) {
		if (srcStr == null || srcStr == "") {
			return "";
		}
		if (splitChar == null || splitChar == "") {
			splitChar = "/";
		}

		return srcStr.substring(srcStr.lastIndexOf(splitChar) + 1);
	}

	
	/**
	 * 计算当前时间与目标时间差
	 * 
	 * @param  gotime
	 *            目标时间
	 * @throws ErrorException 
	 */
	public static List differ_date(String gotime) throws ErrorException{
		if("".equals(gotime)||gotime==null){
			throw new ErrorException(ErrorCodeEasysp.ERROR_EASYSP_F994_CODE, ErrorCodeEasysp.ERROR_EASYSP_F994_MSG);
		}
		SimpleDateFormat df = new SimpleDateFormat(TransUtilEasysp.dateTimeFormat);
		Date dat=null;
		Date nowdat=null;
		try {
			dat=df.parse(gotime);
			nowdat = df.parse(CalendarUtil.getNowTime(TransUtilEasysp.dateTimeFormat));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		long time =(dat.getTime()-nowdat.getTime());
		long month =time/(30*24*60*60*1000l);
		long day=(time-month*(30*24*60*60*1000l))/(24*60*60*1000);  
		long h=(time-(day*(24*60*60*1000)+month*(30*24*60*60*1000l)))/(60*60*1000);
		long m=(time-(day*(24*60*60*1000)+h*(60*60*1000)+month*(30*24*60*60*1000l)))/(60*1000);
		long s=(time-(day*(24*60*60*1000)+h*(60*60*1000)+m*(60*1000)+month*(30*24*60*60*1000l)))/1000;
		List<Object> list=new ArrayList<Object>();
		list.add(month);
		list.add(day);
		list.add(h);
		list.add(m);
		list.add(s);
		return list;
	}
	
	// 不满足登陆密码格式的返回true
	public static boolean isNumeric(String pwd) {
		boolean flag = true;
		// 长度验证，不满足返回true，
		if (pwd.length() >= 6 && pwd.length() <= 12) {
			flag = false;
		}
		if (!flag) {
			flag = true;
			// 如果是纯数字返回true
			if (!pwd.matches("[a-zA-Z]+")) {
				flag = false;
			}
		}

		//验证是否是纯字母
		if (!flag) {
			flag = true;
			// 如果是纯字母返回true
			for (int i = 0; i < pwd.length(); i++) {
				if (!Character.isDigit(pwd.charAt(i))) {
					flag = false;
					break;
				}
			}
		}
		return flag;
	}
	
	/**
	 * 得到一个新的consumerbean
	 * @param user_id  如果没有就传空
	 * @param transBean
	 */
	public static ConsumerBean getNewConsumerBean(String user_id,TransBean transBean){

		//交易流水
		String transId =(String)transBean.getLocalParam(TransConstEasysp.TRANS_ID); 
		//用户id
		String custId = (String)transBean.getLocalParam("user_id");
		//交易码
		String transCode = (String)transBean.getLocalParam(TransConstEasysp.TRANS_CODE);
		//时间
		String timeStamp =CalendarUtil.getDateTime() ;
		//系统编号
		String systemId =Global.getGlobalConf("Global.G_SYSTEM_ID") ;
		//渠道类型
		String channelId =(String)transBean.getLocalParam(TransConstEasysp.CHANNEL_ID) ;
		
		ConsumerBean consumerBean=new ConsumerBean(transId,user_id,transCode,timeStamp,systemId,channelId,TransConstEasysp.NODE_ID);
	
		return consumerBean;
	}
	

	/**
	 * 验证服务返回码
	 * @throws ErrorException 
	 */
	public static void verifyServiceReturn(RpcBean rpcBean) throws ErrorException{
		if(!rpcBean.getRetCode().equals(ErrorCodeEasysp.RET_SUC_CODE)){
			throw new ErrorException(rpcBean.getRetCode(),rpcBean.getRetMsg());
		}
	}
	public static String generateShortUuid() {
		StringBuffer shortBuffer = new StringBuffer();
		String uuid = UUID.randomUUID().toString().replace("-", "");
		for (int i = 0; i < 8; i++) {
			String str = uuid.substring(i * 4, i * 4 + 4);
			int x = Integer.parseInt(str, 16);
			shortBuffer.append(chars[x % 0x3E]);
		}
		return shortBuffer.toString();

	}
	
	//判断用户安全步骤是否存在
	public static boolean chkCustSecurityStep (TransBean transBean) throws ErrorException{
		//获取用户安全步骤完成标识
		ConsumerBean consumerBean = ConsumerBeanUtil.getConsumerBean(transBean, new String[]{"user_id","step_id"});
		RpcBean rpcBean = null;
		try {
			rpcBean=chkAcctSecurityStepService.execute(consumerBean);		
			TransUtilEasysp.verifyServiceReturn(rpcBean);
		} catch (RpcException e) {
			throw new ErrorException(ErrorCodeEasysp.ERROR_9990_CODE,ErrorCodeEasysp.ERROR_9990_MSG);
		}
		transBean.addLocalParam("flag", rpcBean.getResponseParam("flag"));
		if("0".equals(transBean.getLocal("flag"))){
			return false;
		}
		
		return true;
	}
	
	//查询用户安全等级
	public static void getCustSecurityStep(TransBean transBean) throws ErrorException{
		ConsumerBean consumerBeanacct=ConsumerBeanUtil.getConsumerBean(transBean, new String[]{"user_id"});
		RpcBean rpcBean = null;
		//获取用户安全状态
		try {
			System.out.println(qryAcctSecurityStepService);
			rpcBean=qryAcctSecurityStepService.execute(consumerBeanacct);		
			TransUtilEasysp.verifyServiceReturn(rpcBean);
		} catch (RpcException e) {
			throw new ErrorException(ErrorCodeEasysp.ERROR_9990_CODE,ErrorCodeEasysp.ERROR_9990_MSG);
		}
		transBean.addLocalParam("acctstep_list", rpcBean.getResponseParam("acctstep_list"));
		
	}
	
	//翻译用户安全等级
	public static String transLevel(String level){
		switch (level) {
		case TransConstEasysp.SECURITY_TRANSTYPE_LEVEL_INIT://仅注册
			level=TransConstEasysp.BUSI_ACCTSAFE_REGIST;
			break;
		case TransConstEasysp.SECURITY_TRANSTYPE_LEVEL_SETPWD://设置交易密码
			level=TransConstEasysp.BUSI_ACCTSAFE_TRANSPWD; 
			break;
		case TransConstEasysp.SECURITY_TRANSTYPE_LEVEL_BINDING://绑卡and实名认证
			level=TransConstEasysp.BUSI_ACCTSAFE_REALNAME;
			break;
		case TransConstEasysp.SECURITY_TRANSTYPE_LEVEL_RISKASSESS://已风评
			level=TransConstEasysp.BUSI_ACCTSAFE_RISK;
			break;
		
		}
		return level;
	}
	public static boolean stringEquals(String values,String flag){
		String value[] = values.split("\\|");
		for (String v : value) {
			if(flag.equals(v)){
				return true;
			}
		}
		return false;
	}
	
	@SuppressWarnings("static-method")
	public static void addTolistAsmap(List<Map<String,Object>> list, String key, Object val){
		if(null!=list){
			Map<String,Object> map = new HashMap<String,Object>();
			map.put(key, val);
			list.add(map);
		}
	}
	
	//将list中map的key对应的值取出来组成一个字符串数组
	public static String[] listToStrArray(List<Map<String,Object>> list, String key){
		if(null==list || list.size()<1){
			return new String[]{};
		}
		String[] array = new String[list.size()];
		for(int i=0;i<list.size();i++){
			Map<String,Object> map = list.get(i);
			if(map.containsKey(key)){
				array[i] = map==null ? null : (String)map.get(key);
			}
		}
		return array;
	}
	
	//将str中的hideLen位置换为*号
	public static String getMiddleHideStr(String str, int hideLen){
		int len = (str == null ? 0 : str.length());
		char[] ss = str.toCharArray();
		if(len > 0){
			int startindex = (len - hideLen)/2;
			for(int i=0; i<len; i++){
				if(i >= startindex && i < startindex+hideLen){
					ss[i] = '*';
				}
			}
		}
		return new String(ss);
	}
	
	//将字符串保留前4位后4位，其他置为*;返回的长度为taglen位,不足位的在中间补*
	public static String getTwoendsHideFourStr(String str, int tagLen){
		str = str == null ? "" : str;
		int len = str.length();
		char[] strcc = str.toCharArray();
		
		int sideLen = str.length()/2;
		sideLen = sideLen > 4 ? 4 : sideLen; //两边需要保留原字符的长度
		
		tagLen = tagLen < 0 ? len : tagLen;
		char[] tagcc = new char[tagLen];
		
		for(int i=0;i<tagLen;i++){
			if(i < sideLen){
				tagcc[i] = strcc[i];
			}else if(i >= tagLen - sideLen){
				tagcc[i] = strcc[len - (tagLen - i)];
			}else{
				tagcc[i] = '*';
			}
		}
		
		return new String(tagcc);
	}
	
	public static void convertConTwo(TransBean transBean, String key){
		Object val = transBean.getLocalParam(key);
		if(val!=null){
			int index = val.toString().indexOf("-");
			if(index>=0){
				transBean.addLocalParam(key+"_min", val.toString().substring(0, index));
				transBean.addLocalParam(key+"_max", val.toString().substring(index+1));
			}else{
				transBean.addLocalParam(key+"_min", "");
				transBean.addLocalParam(key+"_max", val);
			}
		}
	}
	
	//处理姓名
	public static String formatName(Object name) {
		if(name==null){
			return "";
		}else{
			return name.toString().replaceAll("^.", "*");
		}
	}
	//处理手机号
	public static String formatPhone(Object phone) {
		StringBuffer sb = new StringBuffer(phone.toString());
		return sb.replace(3,7, "****").toString();
	}
	
	/**
	 * 判断是否是正确的EMAIL(邮箱)
	 *
	 * @param idno
	 * @return
	 */
	public static boolean isEmail(String email) {
		return Pattern.matches(EMAIL, email);
	}
	

	public static List<byte[]> FileToList(CommonsMultipartFile[] files) {
		List<byte[]> fileBytesList = new ArrayList<byte[]>();
		try {
			int n = -1;
			byte[] b = new byte[10240];
			InputStream in = files[0].getInputStream();
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			while ((n = in.read(b)) != -1) {
				baos.write(b, 0, n);
				byte[] t = new byte[b.length];
				fileBytesList.add(t);
			}
			in.close();
			InputStream in2 = new ByteArrayInputStream(baos.toByteArray());
			for (byte[] t1 : fileBytesList) {
				in2.read(t1);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return fileBytesList;
	}
	
	public static List<byte[]> FileToList(File file) throws IOException{
		List<byte[]> fileBytesList = new ArrayList<byte[]>();
		int n = -1;
		byte[] b = new byte[10240];
		InputStream in = new FileInputStream(file);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		while ((n = in.read(b)) != -1) {
			baos.write(b, 0, n);
			byte[] t = new byte[n];
			fileBytesList.add(t);
		}
		in.close();
		InputStream in2 = new ByteArrayInputStream(baos.toByteArray());
		for (byte[] t1 : fileBytesList) {
			in2.read(t1);
		}
		return fileBytesList;
	}
	/**
     * 向指定URL发送GET方法的请求
     * 
     * @param url
     *            发送请求的URL
     * @param param
     *            请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }
    public static File ListToFile(List<byte[]> fileBytesList,String fileName) throws IOException{
		File file = new File(UUID.randomUUID().toString().replace("-", "")+fileName);
		FileOutputStream os = new FileOutputStream(file);
        
        //以写字节的方式写文件  
        int n = -1;  
	    for(byte[] b:fileBytesList){  
	    	os.write(b, 0, b.length);  
	    }    
        os.close();  
        os.flush();
        return file;
	}
    
    public static File byte2File(byte[] buf, String filePath, String fileName)  
    {  
         BufferedOutputStream bos = null;  
         FileOutputStream fos = null;  
         File file = null;  
         try  
         {  
             File dir = new File(filePath);  
             if (!dir.exists() && dir.isDirectory())  
             {  
                 dir.mkdirs();  
             }  
             file = new File(filePath + File.separator + fileName);  
             fos = new FileOutputStream(file);  
             bos = new BufferedOutputStream(fos);  
             bos.write(buf);  
             return file;
         }  
         catch (Exception e)  
         {  
             e.printStackTrace();  
             return null;
         }  
         finally  
         {  
             if (bos != null)  
             {  
                 try  
                 {  
                     bos.close();  
                 }  
                 catch (IOException e)  
                 {  
                     e.printStackTrace();  
                 }  
             }  
             if (fos != null)  
             {  
                 try  
                 {  
                     fos.close();  
                 }  
                 catch (IOException e)  
                 {  
                     e.printStackTrace();  
                 }  
             }  
         }  
     }  
    
    /** 
	  * 删除文件，可以是文件或文件夹 
	  *  
	  * @param fileName 
	  *            要删除的文件名 
	  * @return 删除成功返回true，否则返回false 
	  */ 
	public static boolean deleteFileOrDirectory(String fileName) {  
	  File file = new File(fileName);  
	  if (!file.exists()) {  
	   System.out.println("删除文件失败:" + fileName + "不存在！");  
	   return false;  
	  } else {  
	   if (file.isFile())  
	    return deleteFile(fileName);  
	   else  
	    return deleteDirectory(fileName);  
	  }  
	 }  
	/** 
	  * 删除单个文件 
	  *  
	  * @param fileName 
	  *            要删除的文件的文件名 
	  * @return 单个文件删除成功返回true，否则返回false 
	  */
	public static boolean deleteFile(String fileName) {  
		  File file = new File(fileName);  
		  // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除  
		  if (file.exists() && file.isFile()) {  
		   if (file.delete()) {  
		    System.out.println("删除单个文件" + fileName + "成功！");  
		    return true;  
		   } else {  
		    System.out.println("删除单个文件" + fileName + "失败！");  
		    return false;  
		   }  
		  } else {  
		   System.out.println("删除单个文件失败：" + fileName + "不存在！");  
		   return false;  
		  }  
	}  
	/** 
	  * 删除目录及目录下的文件 
	  *  
	  * @param dir 
	  *            要删除的目录的文件路径 
	  * @return 目录删除成功返回true，否则返回false 
	  */  
	public static boolean deleteDirectory(String dir) {  
		  // 如果dir不以文件分隔符结尾，自动添加文件分隔符  
		  if (!dir.endsWith(File.separator))  
		   dir = dir + File.separator;  
		  File dirFile = new File(dir);  
		  // 如果dir对应的文件不存在，或者不是一个目录，则退出  
		  if ((!dirFile.exists()) || (!dirFile.isDirectory())) {  
		   System.out.println("删除目录失败：" + dir + "不存在！");  
		   return false;  
		  }  
		  boolean flag = true;  
		  // 删除文件夹中的所有文件包括子目录  
		  File[] files = dirFile.listFiles();  
		  for (int i = 0; i < files.length; i++) {  
		   // 删除子文件  
		   if (files[i].isFile()) {  
		    flag = deleteFile(files[i].getAbsolutePath());  
		    if (!flag)  
		     break;  
		   }  
		   // 删除子目录  
		   else if (files[i].isDirectory()) {  
		    flag = deleteDirectory(files[i]  
		      .getAbsolutePath());  
		    if (!flag)  
		     break;  
		   }  
		  }  
		  if (!flag) {  
		   System.out.println("删除目录失败！");  
		   return false;  
		  }  
		  // 删除当前目录  
		  if (dirFile.delete()) {  
		   System.out.println("删除目录" + dir + "成功！");  
		   return true;  
		  } else {  
		   return false;  
		  }  
		 }  
    
	public static void main(String[] args) throws ErrorException {
		System.out.println(getTwoendsHideFourStr("4210831990031212123",16));
		System.out.println(formatName("黎维帅"));
		System.out.println(formatPhone("18707166736"));
		System.out.println(getMiddleHideStr("18707166736",6));
		System.out.println(differ_date("20170308115919").toString());
	}

}
